import {
  _decorator,
  Component,
  Vec2,
  v2,
  Animation,
  Node,
  RigidBody2D,
  Collider2D,
  v3,
  misc,
  Prefab,
  instantiate,
  Vec3,
  Physics2DUtils,
  PhysicsSystem2D,
} from "cc";
import { EventManager, MyEvent } from "./AshFramework/Managers/EventManager";
import { MapCamera } from "./Game/MapCamera";
import { PrefsManager } from "./AshFramework/Managers/PrefsManager";
import { PROPS, WEAPON } from "./AshFramework/Datas/Constant";
import { Weapon } from "./Game/Weapon";
import { ZTool } from "./AshFramework/Utils/ZTool";
import { GameData } from "./Game/GameData";
import { BundleManager, Bundles } from "./AshFramework/Managers/BundleManager";
import { GameWeapon } from "./Game/GameWeapon";
import { TLWLSJ_UIManager } from "./Game/UIManager";
import { GameManager } from "./Game/GameManager";
import { MapController } from "./Game/MapController";

const { ccclass, property } = _decorator;

@ccclass("InputManager")
export default class PlayerController extends Component {
  public static Instance: PlayerController = null;
  static MAXHP = 1000;
  static oriPosition: Vec2 = v2();

  rigidbody: RigidBody2D = null;
  collider: Collider2D = null;

  x: number = 0;
  y: number = 0;

  isCooldown: boolean = true; //射击冷却
  isReload: boolean = false; //换弹
  cooldownTimer: number = 0;
  harm: number = 0;
  armorPenetration: number = 0;
  maxSpeed: number = 50;
  speed: number = 50;

  CurHp: number = 0;


  Weapon: Node = null;
  WeaponData: Weapon = null;
  WeaponTs: GameWeapon = null;

  DirX: number = 1;
  DirY: number = -0.1;

  IsRecoil: boolean = false;

  onLoad() {
    PlayerController.Instance = this;
    this.rigidbody = this.node.getComponent(RigidBody2D);
    this.collider = this.node.getComponent(Collider2D);

    PhysicsSystem2D.instance.enable = true;
    // PhysicsSystem2D.instance.debugDrawFlags = 1;


    this.Weapon = this.node.getChildByName("武器");
  }

  start() {
    MapCamera.Instance.Target = this.node;
    this.CurHp = PlayerController.MAXHP;
  }

  showWeapon() {
    const weaponName: string = ZTool.GetEnumKeyByValue(WEAPON, PrefsManager.Instance.userData.CurWeapon);
    this.WeaponData = GameData.getWeaponByName(weaponName);
    this.cooldownTimer = this.WeaponData.CoolingTime;
    this.harm = this.WeaponData.Harm;
    this.armorPenetration = this.WeaponData.ArmorPenetration;
    this.Weapon.removeAllChildren();
    BundleManager.LoadPrefab(Bundles.Prefabs, `武器_${weaponName}`).then(
      (prefab: Prefab) => {
        const weapon: Node = instantiate(prefab);
        weapon.parent = this.Weapon;
      }
    );
  }

  SetMoveDir(x: number, y: number, rate: number) {
    this.x = x;
    this.y = y;
    this.speed = this.maxSpeed * rate;
  }

  SetPlayerDir(x: number, y: number) {
    this.DirX = x;
    this.DirY = y;
    this.node.scale = x < 0 ? v3(-1, 1, 1) : v3(1, 1, 1);

    let angleRadians = Math.atan2(y, x);
    let angleDegrees = misc.radiansToDegrees(angleRadians);

    this.Weapon.angle =
      (angleDegrees > 90 && angleDegrees <= 180) ||
        (angleDegrees < -90 && angleDegrees >= -180)
        ? 180 - angleDegrees
        : angleDegrees;
  }

  StopMove() {
    this.x = 0;
    this.y = 0;
    if (this.rigidbody.enabled) {
      this.rigidbody.linearVelocity = v2(this.x, this.y);
    }
  }

  update(dt) {
    if (this.rigidbody.enabled && !this.IsRecoil) {
      this.rigidbody.linearVelocity = v2(
        this.x * this.speed,
        this.y * this.speed
      );
    }
  }

  // 施加后坐力的方法
  applyRecoil(recoilStrength: number) {
    // if (!this.rigidbody || this.IsRecoil) return;
    if (this.IsRecoil) return;
    this.IsRecoil = true;
    this.rigidbody.linearVelocity = v2(0, 0);
    const direction: Vec2 = v2(this.DirX, this.DirY).normalize();
    // 施加冲量（impulse）模拟后坐力
    const recoilImpulse = direction.multiplyScalar(-recoilStrength);
    this.rigidbody.applyForceToCenter(recoilImpulse, true);
  }
  retrogress() { }

  hit(harm: number) {
    this.CurHp -= harm;
    if (this.CurHp <= 0) {
      this.CurHp = 0;
      GameManager.Instance.IsPause = true;
      TLWLSJ_UIManager.Instance.showTips("玩家死亡，游戏失败！", () => {
        GameManager.Instance.gameFail();
      });
      //玩家死亡
    } else if (this.CurHp <= 200) {
      //玩家濒死状态
      TLWLSJ_UIManager.Instance.showAgonalStaged();
    } else {
      // UIManager.Instance.closeAgonalStaged();
      TLWLSJ_UIManager.Instance.showAgonalStagedOnce();
    }
    TLWLSJ_UIManager.Instance.setHPFillRange(this.CurHp / PlayerController.MAXHP);
  }

  cure(hp: number = PlayerController.MAXHP) {
    this.CurHp += hp;
    this.CurHp = ZTool.Clamp(this.CurHp, 0, PlayerController.MAXHP);
    if (this.CurHp > 200) {
      //玩家濒死状态
      TLWLSJ_UIManager.Instance.closeAgonalStaged();
    }
    TLWLSJ_UIManager.Instance.setHPFillRange(this.CurHp / PlayerController.MAXHP);
  }

  propCure(type: PROPS) {
    if (type == PROPS.药丸) {
      this.cure(200);
    } else if (type == PROPS.咖啡) {
      this.cure(800);
    }
  }

  isCure() {
    if (this.CurHp >= PlayerController.MAXHP) return false;
    return true;
  }

  protected onEnable(): void {
    EventManager.Scene.on(MyEvent.MOVEMENT, this.SetMoveDir, this);
    EventManager.Scene.on(MyEvent.MOVEMENT_STOP, this.StopMove, this);
    EventManager.Scene.on(MyEvent.SET_ATTACK_DIR, this.SetPlayerDir, this);
  }

  protected onDisable(): void {
    EventManager.Scene.off(MyEvent.MOVEMENT, this.SetMoveDir, this);
    EventManager.Scene.off(MyEvent.MOVEMENT_STOP, this.StopMove, this);
    EventManager.Scene.off(MyEvent.SET_ATTACK_DIR, this.SetPlayerDir, this);
  }

  //#region 玩家数值
}
